#ifndef filelistH
#define filelistH

#include "wx/string.h"
#ifdef __WINDOWS__
#include <windows.h>
#endif //__WINDOWS__

struct FileInfo
{
	public:
		wxString sName;
		wxDateTime dtCreated;
		wxDateTime dtModified;
		unsigned long uiSizeHigh;
		unsigned long uiSizeLow;
		bool bCompressed;
#ifdef __WINDOWS__
		DWORD dwAttr;
#endif //__WINDOWS__
		FileInfo(void)
		{
			bCompressed = false;
			dtCreated.Set(0lL);
			dtModified.Set(0lL);
#ifdef __WINDOWS__
			dwAttr = 0;
#endif //__WINDOWS__
		}
		FileInfo(FileInfo* src)
			: dtCreated(src->dtCreated)
			, dtModified(src->dtModified)
			, uiSizeHigh(src->uiSizeHigh)
			, uiSizeLow(src->uiSizeLow)
			, bCompressed(src->bCompressed)
		{
			sName = src->sName;
#ifdef __WINDOWS__
			dwAttr = src->dwAttr;
#endif //__WINDOWS__
		}
	FileInfo & operator=(FileInfo &src)
	{
		if( &src != this )
		{
			sName = src.sName;
			bCompressed = src.bCompressed;
			dtCreated = src.dtCreated;
			dtModified = src.dtModified;
			uiSizeLow = src.uiSizeLow;
			uiSizeHigh = src.uiSizeHigh;
#ifdef __WINDOWS__
			dwAttr = src.dwAttr;
#endif //__WINDOWS__
		}
		return *this;
	}
	bool operator==(FileInfo &src)
	{
		return sName == src.sName
			&& dtCreated.IsEqualTo(src.dtCreated)
			&& dtModified.IsEqualTo(src.dtModified)
			&& uiSizeHigh == src.uiSizeHigh
			&& uiSizeLow == src.uiSizeLow
#ifdef __WINDOWS__
			&& dwAttr == src.dwAttr
#endif //__WINDOWS__
			;
	}
	bool operator!=(FileInfo &src)
	{
		return !operator==(src);
	}
};

WX_DECLARE_LIST(FileInfo, FileInfoList);

#include "wx/stream.h"

class FileThread;

class Files
{
	public:
		wxString sPath;
		Files(CommandParams *_cp, const wxString &path, FileThread *_fth) : cp(_cp), sPath(path), fth(_fth)
		{
			fiList = new FileInfoList(wxKEY_STRING);
		}
		virtual ~Files(void)
		{
			filClear(fiList);
			delete fiList;
		}
		virtual void FillFilesInfo(void) = 0;
		DWORD Add(Files*, bool);
		void Replace(Files*);
		void Remove(Files*, bool);
		FileInfoList::Node* GetFirst(void)
		{
			return fiList->GetFirst();
		}
		virtual HANDLE GetInputStream(FileInfo*) = 0; 
		virtual HANDLE GetOutputStream(FileInfo*) = 0; 
		virtual bool DeleteFile(const wxString &) = 0;
		/*virtual void MkDir(const wxString &) = 0;*/
		virtual void RmDir(const wxString &) = 0;
		virtual bool DirExists(const wxString &) = 0;
		
		int GetCount(void)
		{
			return fiList->GetCount();
		}
	protected:
		size_t bs;
		char *buf;
		CommandParams *cp;
		FileInfoList *fiList;
		FileThread *fth;
		void checkTerminated(void);
		void createDir(const wxString&);
		void filClear(FileInfoList *);
		virtual void FindFiles(const wxString &) = 0;
		virtual DWORD copyFile(HANDLE, HANDLE) = 0;
		void MakeDir(wxString);
};

class LocalFiles : public Files
{
	public:
		LocalFiles(CommandParams *_cp, const wxString &path, FileThread *_fth, bool createFirst = false) : Files(_cp, path, _fth), _createFirst(createFirst)
		{}
		virtual void FillFilesInfo(void);
		virtual HANDLE GetInputStream(FileInfo*); 
		virtual HANDLE GetOutputStream(FileInfo*); 
		virtual bool DeleteFile(const wxString &);
		/*virtual void MkDir(const wxString &);*/
		virtual void RmDir(const wxString &);
		virtual bool DirExists(const wxString &);
	protected:
		bool _createFirst;
		virtual DWORD copyFile(HANDLE, HANDLE);
		virtual void FindFiles(const wxString &);
		void FindDirs(const wxString &);
};

wxString getFileName(const wxString&);
wxString getFileSize(const wxString&);
wxString completePath(const wxString&);
void MakeDir(wxString);

#endif

